package com.generator.factory;

import com.generator.domain.ColumnDO;
import com.generator.domain.TableDO;
import com.generator.helper.TableHelper;
import com.generator.utils.DateUtils;
import com.google.common.collect.Lists;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 〈template  〉
 *
 * @author xsh
 * @create 2018/9/18
 * @since 1.0.0
 */
@Component
public class TemplateFactory {

     @Autowired
     private TableHelper tableHelper ;

     public static List<String>  getTemplates(){
          List<String>  templates = Lists.newArrayList();
          String userDir = System.getProperty("user.dir");
          String base = "src/main/resources/";
          templates.add(base+"templates/generator/domain.java.ftl");
          templates.add(base+"templates/generator/Dao.java.ftl");
          templates.add(base+"templates/generator/Mapper.xml.ftl");
          templates.add(base+"templates/generator/Service.java.ftl");
          templates.add(base+"templates/generator/ServiceImpl.java.ftl");
          templates.add(base+"templates/generator/Controller.java.ftl");
          templates.add(base+"templates/generator/list.html.ftl");
        //  templates.add(base+"templates/generator/add.html.ftl");
        //  templates.add(base+"templates/generator/edit.html.ftl");
          templates.add(base+"templates/generator/list.js.ftl");
//          templates.add(base+"templates/generator/add.js.ftl");
//          templates.add(base+"templates/generator/edit.js.ftl");
          return templates;
     }


     public   void  generatorCode(String  tableName) throws  Exception{
          org.apache.commons.configuration.Configuration  config = TableHelper.getConfig();
          TableDO tableDO = tableHelper.buildTable(tableName);
          List<ColumnDO>  columnDOS = tableHelper.buildColumns(tableName,tableDO);
          tableDO.setColumns(columnDOS);
          //没主键，则第一个字段为主键
          if (tableDO.getPk() == null) {
               tableDO.setPk(tableDO.getColumns().get(0));
          }
          //封装模板数据
          Map<String, Object> map = new HashMap<>(16);
          map.put("tableName", tableDO.getTableName());
          map.put("comments", tableDO.getComment());
          map.put("pk", tableDO.getPk());
          map.put("className", tableDO.getClassName());
          map.put("classname", tableDO.getClassname());
          if (tableDO.getHasBigDecimal()==null){
               map.put("hasBigDecimal","false");
          }else{
               map.put("hasBigDecimal",tableDO.getHasBigDecimal());
          }
          map.put("pathName", config.getString("package").substring(config.getString("package").lastIndexOf(".") + 1));
          map.put("columns", tableDO.getColumns());
          map.put("package", config.getString("package"));
          map.put("author", config.getString("author"));
          map.put("email", config.getString("email"));
          map.put("datetime", DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN));

         // String templateDirtory =
          Configuration configuration =  new Configuration(Configuration.VERSION_2_3_0);
          configuration.setDefaultEncoding("UTF-8");
          List<String>  templates = getTemplates();
          for (String templateFile :templates){
               Template template = configuration.getTemplate(templateFile,"UTF-8");
               String target_file = config.getString("saveDir")+getFileName(templateFile, tableDO.getClassname(), tableDO.getClassName(), config.getString("package").substring(config.getString("package").lastIndexOf(".") + 1));
               File  file = new File(target_file);
               if (!file.exists()){
                    file.createNewFile();
               }
               BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(target_file)));
               template.process(map,writer);
               writer.close();
          }
     }


     private static String getFileName(String template, String classname, String className, String packageName) {
          String packagePath = "main" + File.separator + "java" + File.separator;
          //String modulesname=config.getString("packageName");
          if (StringUtils.isNotBlank(packageName)) {
               packagePath += packageName.replace(".", File.separator) + File.separator;
          }

          if (template.contains("domain.java.ftl")) {
              // return packagePath + "domain" + File.separator + className + "DO.java";
               return  className + "DO.java";
          }

          if (template.contains("Dao.java.ftl")) {
               return  className + "Dao.java";
          }

//		if(template.contains("Mapper.java.vm")){
//			return packagePath + "dao" + File.separator + className + "Mapper.java";
//		}

          if (template.contains("Service.java.ftl")) {
               return className + "Service.java";
          }

          if (template.contains("ServiceImpl.java.ftl")) {
               return className + "ServiceImpl.java";
          }

          if (template.contains("Controller.java.ftl")) {
               return  className + "Controller.java";
          }

          if (template.contains("Mapper.xml.ftl")) {
              // return "main" + File.separator + "resources" + File.separator + "mapper" + File.separator + packageName + File.separator + className + "Mapper.xml";
               return  className + "Mapper.xml";
          }

          if (template.contains("list.html.ftl")) {
//               return "main" + File.separator + "resources" + File.separator + "templates" + File.separator
//                       + packageName + File.separator + classname + File.separator + classname + ".html";
               //				+ "modules" + File.separator + "generator" + File.separator + className.toLowerCase() + ".html";
               return  classname + ".html";
          }
          if (template.contains("add.html.ftl")) {
//               return "main" + File.separator + "resources" + File.separator + "templates" + File.separator
//                       + packageName + File.separator + classname + File.separator + "add.html";
               return  "add.html";
          }
          if (template.contains("edit.html.vm")) {
//               return "main" + File.separator + "resources" + File.separator + "templates" + File.separator
//                       + packageName + File.separator + classname + File.separator + "edit.html";
               return "edit.html";
          }

          if (template.contains("list.js.ftl")) {
//               return "main" + File.separator + "resources" + File.separator + "static" + File.separator + "js" + File.separator
//                       + "appjs" + File.separator + packageName + File.separator + classname + File.separator + classname + ".js";
               //		+ "modules" + File.separator + "generator" + File.separator + className.toLowerCase() + ".js";

               return className.toLowerCase() + ".js";
          }
          if (template.contains("add.js.ftl")) {
//               return "main" + File.separator + "resources" + File.separator + "static" + File.separator + "js" + File.separator
//                       + "appjs" + File.separator + packageName + File.separator + classname + File.separator + "add.js";

               return "add.js";
          }
          if (template.contains("edit.js.ftl")) {
//               return "main" + File.separator + "resources" + File.separator + "static" + File.separator + "js" + File.separator
//                       + "appjs" + File.separator + packageName + File.separator + classname + File.separator + "edit.js";
               return "edit.js";
          }

//		if(template.contains("menu.sql.vm")){
//			return className.toLowerCase() + "_menu.sql";
//		}
          return null;
     }

}